package it.uniba.di.mas.jpnde.core;

import bsh.Interpreter;

import jade.util.Logger;
import jade.util.leap.ArrayList;
import jade.util.leap.HashMap;
import jade.util.leap.List;
import jade.util.leap.Map;
import jade.util.leap.Serializable;

public class Script implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ArrayList imports=null;
	private ArrayList functions=null;
	private Map returnValues=null;
	
	private Logger logger=null;

	public Script(){
		imports=new ArrayList();
		functions=new ArrayList();
	}
	
	public void clear(){
		imports=new ArrayList();
		functions=new ArrayList();
	}
	
	public void addImport(ScriptImport sImport){
		imports.add(sImport);
	}
	public void addFunction(ScriptFunction sFunction){
		functions.add(sFunction);
	}
	
	public boolean existFunction(String event){
		boolean bExist=false;
		for(int i=0;i<functions.size();i++){
			ScriptFunction function=(ScriptFunction)functions.get(i);
			if (function.getOnEvent().equalsIgnoreCase(event)){
				bExist=true;
				break;
			}
		}
		return bExist;
	}
	
	public void execute(String event,List vars)
		throws Exception
	{
		boolean bExist=false;
		logger=Logger.getMyLogger(this.getClass().getName());
		returnValues=new HashMap();
		
		for(int i=0;i<functions.size();i++){
			ScriptFunction function=(ScriptFunction)functions.get(i);
			if (function.getOnEvent().equalsIgnoreCase(event)){
				bExist=true;
				
				Interpreter engine = new Interpreter();
				
				for(int j=0;j<vars.size();j++)
					{
					TaggedValue tv=(TaggedValue)vars.get(j);
					engine.set(tv.getName(), tv.getValue());
					}
				
				engine.eval("import it.uniba.di.mas.jpnde.core.*;");
				
				for(int j=0;j<imports.size();j++){
					ScriptImport sImport=(ScriptImport)imports.get(j);
					String stmt="import "+sImport.getPackage()+";";
					logger.log(Logger.INFO,stmt);
					engine.eval(stmt);
				}
				String stmt=(function.getBody().replaceAll("\n", "")).replaceAll("\r", "");
				logger.log(Logger.INFO,stmt);
				engine.eval(stmt);
				if (event.equalsIgnoreCase(ScriptFunction.ON_ACTIVATION))
					returnValues.put("tokenOut", engine.get("tokenOut"));
				if (event.equalsIgnoreCase(ScriptFunction.ON_ADD))
					returnValues.put("token", engine.get("token"));
	
			}
		}
		
		if (!bExist)
			throw new Exception("Function on <"+event+"> not found !");
		
	}
	
	public Map getReaturnValues(){
		return returnValues;
	}
	
	public String toString() {
		return "Script [imports=" + imports +", functions=" + functions +"]";
	}
}
